package com.peng.rpc.netty.util;

import com.peng.rpc.entity.RpcRequest;
import com.peng.rpc.entity.RpcResponse;
import com.peng.rpc.enumeration.PackageType;
import com.peng.rpc.serializer.CommonSerializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * 自定义协议：
 * +---------------+---------------+-----------------+-------------+
 * |  Magic Number |  Package Type | Serializer Type | Data Length |
 * |    4 bytes    |    4 bytes    |     4 bytes     |   4 bytes   |
 * +---------------+---------------+-----------------+-------------+
 * |                          Data Bytes                           |
 * |                   Length: ${Data Length}                      |
 * +---------------------------------------------------------------+
 * @author Wonderson
 * @email wpp.ds@foxmail.com
 * @date 2022/3/1 20:21
 */
public class CommonEncoder extends MessageToByteEncoder {
    /**
     * 魔数：标记这是一个协议包开始
     */
    public static final int MAGIC_NUMBER = 0xCAFEBABE;

    private final CommonSerializer commonSerializer;

    public CommonEncoder(CommonSerializer commonSerializer) {
        this.commonSerializer = commonSerializer;
    }


    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Object msg, ByteBuf out) throws Exception {
        //1. 四字节的魔数
        out.writeInt(MAGIC_NUMBER);

        //2. 四字节的包类型：请求包/响应包
        if (msg instanceof RpcRequest) {
            out.writeInt(PackageType.REQUEST_PACKAGE.getCode());
        } else if (msg instanceof RpcResponse) {
            out.writeInt(PackageType.RESPONSE_PACKAGE.getCode());
        }

        //3. 四字节的序列化方式
        out.writeInt(commonSerializer.getCode());

        byte[] bytes = commonSerializer.serialize(msg);

        //4. 四字节的数据长度【防止粘包】
        out.writeInt(bytes.length);

        //5. 剩下就是数据包的内容
        out.writeBytes(bytes);
    }
}
